package design.onekey.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import design.onekey.base.*;
import design.onekey.constant.enums.*;
import design.onekey.mapper.SysMenuMapper;
import design.onekey.model.*;
import design.onekey.model.dto.*;
import design.onekey.service.IUserRoleFunctionService;
import design.onekey.service.IUserRoleMenuService;
import design.onekey.service.ISysFunctionService;
import design.onekey.service.ISysMenuService;
import design.onekey.util.MessageUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* @Description: SysMenu服务实现
* @author
* @date 2020-06-05 04:03:09
* @version V1.0
*/
@Service
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements ISysMenuService {

   @Autowired
   private ISysFunctionService iSysFunctionService;

   @Autowired
   private IUserRoleFunctionService iUserRoleFunctionService;

   @Autowired
   private IUserRoleMenuService iUserRoleMenuService;

   /**
    * @Fields menuList : 菜单类型
    * @author blcloak
    * @date 2020-07-08 10:08:32
    */
   private static Map<Integer, String> menuMap = new HashMap<Integer, String>();
   static{
       menuMap.put(MenuTypeEnum.ADMIN.getCode(),MenuTypeEnum.ADMIN.getName());
       menuMap.put(MenuTypeEnum.DOCTORPC.getCode(),MenuTypeEnum.DOCTORPC.getName());
   }

   /**
   * @Title: tablePagingQuery
   * @Description: 表格分页查询
   * @param @param model
   * @return BaseEntity
   * @author
   * @throws
   */
   @Override
   public PageEntity tablePagingQuery(SysMenu model) {
       PageEntity result = new PageEntity();
       model.setDelFlag(DelFlagEnum.UNDEL.getCode());
       com.github.pagehelper.Page<?> page = PageHelper.startPage(model.getCurrentPage(), model.getPageSize()); //分页条件
       List<SysMenu> list = this.baseMapper.searchDataLike(model);
       result.setData(list);
       result.setTotal(page.getTotal());
       result.setCurrentPage(model.getCurrentPage());
       result.setPageSize(model.getPageSize());
       return result;
   }


   /**
   *<p>Title: getDetail</p>
   *<p>Description: 获取详情</p>
   * @author
   * @param id
   * @return
   */
   @Override
   public BaseEntity getDetail(Long id) {
       return this.getById(id);
   }

   /**
   *<p>Title: insert</p>
   *<p>Description: 新增数据</p>
   * @author
   * @param model
   * @return
   */
   @Transactional
   @Override
   public BaseEntity insert(SysMenu model, UserInfoDto userInfoDto) {
       BaseEntity result = new BaseEntity();
       if (model.getParentMenuId() == null) {
           model.setParentMenuId(0L);
       }
       this.save(model);
       result.setStatusMsg(MessageUtil.getValue("info.insert"));
       return result;
   }

   /**
   *<p>Title: update</p>
   *<p>Description: 更新数据</p>
   * @author
   * @param model
   * @return
   */
   @Transactional
   @Override
   public BaseEntity update(SysMenu model) {
       BaseEntity result = new BaseEntity();
       this.updateById(model);
       result.setStatusMsg(MessageUtil.getValue("info.update"));
       return result;
   }

   /**
   *<p>Title: delete</p>
   *<p>Description: 单条删除数据</p>
   * @author
   * @param model
   * @return
   */
   @Transactional
   @Override
   public BaseEntity delete(Long id) {
       SysMenu sysMenu = new SysMenu();
       sysMenu.setId(id);
       sysMenu.setDelFlag(DelFlagEnum.DEL.getCode());
       this.updateById(sysMenu);
       BaseEntity result = new BaseEntity();
       result.setStatusMsg(MessageUtil.getValue("info.delete"));
       return result;
   }

   /**
   *<p>Title: deleteBatch</p>
   *<p>Description: 批量删除数据</p>
   * @author
   * @param list
   * @return
   */
   @Transactional
   @Override
   public BaseEntity deleteBatch(List<Long> ids) {
       List<SysMenu> list = new ArrayList<SysMenu>();
       for (int i = 0; i < ids.size(); i++) {
           SysMenu sysMenu = new SysMenu();
           sysMenu.setId(ids.get(i));
           sysMenu.setDelFlag(DelFlagEnum.DEL.getCode());
           list.add(sysMenu);
       }
       BaseEntity result = new BaseEntity();
       if (list != null && list.size() > 0) {
           this.updateBatchById(list);
       }
       result.setStatusMsg(MessageUtil.getValue("info.delete"));
       return result;
   }


   /**
    * @Title: getAuthTree
    * @Description: 获取菜单授权树
    * @param userRole
    * @return
    * @author blcloak
    * @date 2020-06-10 05:05:07
    */
   @Override
   public AuthTreeDto getAuthTree(UserRole userRole, UserInfoDto userInfoDto) {
       AuthTreeDto authTreeDto = new AuthTreeDto();
       List<String> authed = new ArrayList<String>();
       //获取角色已经授权的功能
       QueryWrapper<UserRoleFunction> userRoleFunctionWrapper = new QueryWrapper<UserRoleFunction>();
       userRoleFunctionWrapper.eq("role_id", userRole.getId());
       userRoleFunctionWrapper.eq("del_flag", DelFlagEnum.UNDEL.getCode());
       List<UserRoleFunction> functions = iUserRoleFunctionService.list(userRoleFunctionWrapper);
       if (functions != null && functions.size() > 0) {
           for (UserRoleFunction userRoleFunction : functions) {
               authed.add("api-"+userRoleFunction.getFunctionId());
           }
       }
       authTreeDto.setAuthed(authed);
       List<MenuTreeDto> treeData = new ArrayList<MenuTreeDto>();
       for(Map.Entry<Integer, String> entry : menuMap.entrySet()){
           SysMenuDto sysMenuDto = new SysMenuDto();
           if (YesNoEnum.YES.getCode() == userInfoDto.getIsAdmin()) {
               //超级用户有所有的菜单和功能权限
               sysMenuDto.setIsAdmin(YesNoEnum.YES.getCode());
           }else {
               sysMenuDto.setRoleId(userInfoDto.getRoleId());
           }
           sysMenuDto.setParentMenuId(0L);
           sysMenuDto.setMenuType(entry.getKey());
           sysMenuDto.setRule(MenuRuleEnum.AUTH.getCode());
           //获取有权限的顶级菜单
           List<MenuTreeDto> list = this.baseMapper.getMenuTree(sysMenuDto);
           this.getSubAuthTree(list, authed, userInfoDto, userRole.getId(),entry.getKey());
           MenuTreeDto menuTreeDto = new MenuTreeDto();
           menuTreeDto.setChildren(list);
           menuTreeDto.setMenuName(entry.getValue());
           menuTreeDto.setMenuId("menu-"+entry.getKey());
           if(menuTreeDto.getChildren() != null && menuTreeDto.getChildren().size() > 0)
           {
               treeData.add(menuTreeDto);
           }

       }
       authTreeDto.setTreeData(treeData);
       authTreeDto.setAuthed(authed);
       return authTreeDto;
   }

   /**
    * @Title: getSubAuthTree
    * @Description: 递归获取所有的子菜单和功能
    * @param list
    * @param authed
    * @param userInfoDto
    * @author blcloak
    * @date 2020-06-11 08:36:50
    */
   private void getSubAuthTree(List<MenuTreeDto> list,List<String> authed,UserInfoDto userInfoDto,Long roleId,Integer menuType) {
       if (list != null && list.size() > 0) {
           for (int i = 0; i < list.size(); i++) {
               //获取菜单下的所有子菜单
               SysMenuDto sysMenuDto = new SysMenuDto();
               sysMenuDto.setParentMenuId(list.get(i).getId());
               sysMenuDto.setRule(MenuRuleEnum.AUTH.getCode());
               sysMenuDto.setMenuType(MenuTypeEnum.ADMIN.getCode());
               if (1 == userInfoDto.getIsAdmin()) {
                   //超级用户有所有的菜单和功能权限
                   sysMenuDto.setIsAdmin(1);
               }else {
                   sysMenuDto.setRoleId(userInfoDto.getRoleId());
               }
               List<MenuTreeDto> subMenus = this.baseMapper.getMenuTree(sysMenuDto);
               if (subMenus != null && subMenus.size()>0) {
                   this.getSubAuthTree(subMenus,authed,userInfoDto,roleId,menuType);
               }
               //获取菜单下有权限的接口
               sysMenuDto.setId(list.get(i).getId());
               sysMenuDto.setRule(FunctionRuleEnum.JWTAUTH.getCode());
               List<MenuTreeDto> functions = iSysFunctionService.getMenuFunctions(sysMenuDto);
               if (subMenus == null) {
                   list.get(i).setChildren(functions);
               }else {
                   if (functions == null || functions.size() == 0) {
                       //如果该菜单下没有接口则判断该菜单是否有权限，顶级菜单除外,并且没有子菜单
                       if (0 != list.get(i).getParentMenuId()) {
                           QueryWrapper<SysMenu> menuQueryWrapper = new QueryWrapper<SysMenu>();
                           menuQueryWrapper.eq("parent_menu_id", list.get(i).getId());
                           menuQueryWrapper.eq("del_flag", DelFlagEnum.UNDEL.getCode());
                           List<SysMenu> menus = this.list(menuQueryWrapper);
                           if(menus == null || menus.size()==0)
                           {
                               QueryWrapper<UserRoleMenu> queryWrapper = new QueryWrapper<UserRoleMenu>();
                               queryWrapper.eq("role_id", roleId);
                               queryWrapper.eq("menu_id", list.get(i).getId());
                               queryWrapper.eq("del_flag", DelFlagEnum.UNDEL.getCode());
                               UserRoleMenu userRoleMenu = iUserRoleMenuService.getOne(queryWrapper);
                               if (userRoleMenu != null) {
                                   authed.add(String.valueOf(list.get(i).getId()));
                               }
                           }
                       }
                   }
                   subMenus.addAll(functions);
                   list.get(i).setChildren(subMenus);
               }
           }
       }
   }


   /**
    * @Title: getIndexMenu
    * @Description: 获取首页菜单树
    * @param userInfoDto
    * @return
    * @date 2020-06-11 05:21:25
    */
   @Override
   public List<IndexMenuTreeDto> getIndexMenu(UserInfoDto userInfoDto) {
       SysMenuDto sysMenuDto = new SysMenuDto();
       if (1 == userInfoDto.getIsAdmin()) {
           //超级管理员
           sysMenuDto.setIsAdmin(1);
       }else {
           sysMenuDto.setRoleId(userInfoDto.getRoleId());
       }
       sysMenuDto.setParentMenuId(0L);
       List<IndexMenuTreeDto> list = this.baseMapper.getIndexMenu(sysMenuDto);
       this.getSubIndexMenu(list, userInfoDto);
       return list;
   }

   /**
    * @Title: getSubIndexMenu
    * @Description: 获取子菜单树
    * @param list
    * @param userInfoDto
    * @author blcloak
    * @date 2020-06-11 05:55:27
    */
   private void getSubIndexMenu(List<IndexMenuTreeDto> list,UserInfoDto userInfoDto)
   {
       if (list != null && list.size() > 0) {
           for (int i = 0; i < list.size(); i++) {
               SysMenuDto sysMenuDto = new SysMenuDto();
               if (1 == userInfoDto.getIsAdmin()) {
                   //超级管理员
                   sysMenuDto.setIsAdmin(1);
               }else {
                   sysMenuDto.setRoleId(userInfoDto.getRoleId());
               }
               sysMenuDto.setParentMenuId(list.get(i).getId());
               List<IndexMenuTreeDto> subMenus =  this.baseMapper.getIndexMenu(sysMenuDto);
               list.get(i).setSubs(subMenus);
               this.getSubIndexMenu(subMenus, userInfoDto);
           }
       }
   }


   /**
    * @Title: getAllMenus
    * @Description: 获取所有的后台菜单
    * @return
    * @author blcloak
    * @date 2020-06-16 01:20:30
    */
   @Override
   public List<SysMenu> getAllMenus(SysMenu sysMenu) {
       QueryWrapper<SysMenu> queryWrapper = new QueryWrapper<SysMenu>();
       queryWrapper.eq("del_flag", DelFlagEnum.UNDEL.getCode());
       queryWrapper.eq("is_hidden", 2);
       queryWrapper.eq("menu_type", sysMenu.getMenuType());
       return this.list(queryWrapper);
   }

}
